package com.zensun.web.controller.system;

import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.zensun.common.annotation.Log;
import com.zensun.common.constant.ImgConstants;
import com.zensun.common.constant.UserConstants;
import com.zensun.common.core.controller.BaseController;
import com.zensun.common.core.domain.R;
import com.zensun.common.enums.BusinessType;
import com.zensun.common.utils.Assert;
import com.zensun.common.utils.file.OssFileUtils;
import com.zensun.common.utils.spring.ServletUtils;
import com.zensun.framework.web.service.TokenService;
import com.zensun.system.domain.SysUser;
import com.zensun.system.domain.dto.SysProfilePatchDto;
import com.zensun.system.domain.model.LoginUser;
import com.zensun.system.service.ISysUserService;
import com.zensun.system.util.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 个人信息 业务处理
 *
 * @author gmk
 */
@Api(value = "个人信息", tags = "个人信息模块")
@RestController
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController {
    @Autowired
    private ISysUserService userService;

    @Autowired
    private TokenService tokenService;

    /**
     * 个人信息
     */
    @ApiOperation("获取个人信息")
    @GetMapping
    public R profile() {
        // 1.缓存中取用户信息
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        SysUser user = loginUser.getUser();
        Map<String, Object> map = new HashMap<>();
        map.put("user", user);
        // 2.缓存中取用户信息
        map.put("roleGroup", userService.selectUserRoleGroup(user.getUserId()));
        return R.success(map);
    }

    /**
     * 修改用户
     */
    @ApiOperation("修改个人姓名")
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PatchMapping
    public R updateProfile(@RequestBody SysProfilePatchDto sysProfilePatchDto) {
        checkUserAllowed(sysProfilePatchDto.getUserId());
        if (userService.updateUserProfile(sysProfilePatchDto) > 0) {
            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
            // 更新缓存用户信息姓名
            if (StrUtil.isNotBlank(sysProfilePatchDto.getUserName())) {
                loginUser.getUser().setUserName(sysProfilePatchDto.getUserName());
            }
            tokenService.setLoginUser(loginUser);
            return R.success();
        }
        return R.error("修改个人信息异常，请联系管理员");
    }

    /**
     * 重置密码
     */
    @ApiOperation("重置密码")
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PatchMapping("/updatePwd")
    public R updatePwd(@RequestBody SysProfilePatchDto sysProfilePatchDto) {
        // 1.准备数据
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        //获取用户Id
        Long userId = loginUser.getUser().getUserId();
        String password = loginUser.getPassword();
        // 2.校验
        Assert.isTrue(!SecurityUtils.matchesPassword(sysProfilePatchDto.getOldPassword(), password), "修改密码失败，旧密码错误");
        Assert.isTrue(SecurityUtils.matchesPassword(sysProfilePatchDto.getNewPassword(), password), "新密码不能与旧密码相同");
        // 3.重设密码
        if (userService.resetUserPwd(userId, SecurityUtils.encryptPassword(sysProfilePatchDto.getNewPassword())) > 0) {
            // 4.更新缓存用户密码
            loginUser.getUser().setPassword(SecurityUtils.encryptPassword(sysProfilePatchDto.getNewPassword()));
            tokenService.setLoginUser(loginUser);
            return R.success();
        }
        return R.error("修改密码异常，请联系管理员");
    }

    /**
     * 头像上传
     */
    @ApiOperation("头像上传")
    @Log(title = "用户头像", businessType = BusinessType.UPDATE)
    @PostMapping("/avatar")
    public R avatar(@RequestParam("avatarfile") MultipartFile file) throws IOException {
        if (!file.isEmpty()) {
            // 1.准备数据
            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
            // 校验
            String extension = FileNameUtil.extName(file.getOriginalFilename());
            com.zensun.common.utils.Assert.isNotTrue(ImgConstants.types.contains(extension), "图片类型必须为\"jpg\", \"png\", \"jpeg\"");
            // 2.下载文档
            String url = OssFileUtils.upload(file);
            // 3.更新头像
            if (userService.updateUserAvatar(loginUser.getUsername(), url)) {
                Map<String, Object> map = new HashMap<>();
                map.put("imgUrl", url);
                // 4.更新缓存用户头像
                loginUser.getUser().setAvatar(url);
                tokenService.setLoginUser(loginUser);
                return R.success(map);
            }
        }
        return R.error("上传图片异常，请联系管理员");
    }

    /**
     * 校验用户是否允许操作
     *
     * @param userId 用户Ids
     */
    public void checkUserAllowed(Long userId) {
        com.zensun.common.utils.Assert.isTrue(ObjectUtil.isNotNull(userId) && UserConstants.ADMIN_ID.equals(userId), "不允许操作超级管理员用户");
    }
}
